//工具生成，请不要手动修改...
let ObjEncoder: any, ObjDecoder: any
/** 需要传入kcoder模块来进行初始化 */
export function initProto(kcoder: { ObjEncoder: any, ObjDecoder: any }) {
    ObjEncoder = kcoder.ObjEncoder
    ObjDecoder = kcoder.ObjDecoder
}

/** 协议 */
export const enum Proto {
    /** [客户端请求]加入游戏 */
    C2S_JOIN = 100,
    /** [服务端返回]加入游戏结果 */
    S2C_JOIN = 101,
    /** [客户端请求]准备好接收数据了 */
    C2S_READY = 102,
    /** [服务端返回]玩家信息 */
    S2C_PLAYER_INFO = 200,
    /** [客户端请求]控制角度 */
    C2S_CTRL_TURN = 201,
    /** [客户端请求]控制加速 */
    C2S_CTRL_SPRINT = 202,
    /** [服务端返回]屏幕焦点 */
    S2C_SCREEN_FOCUS = 300,
    /** [服务端返回]蛇更新 */
    S2C_SNAKE_UPDATE = 400,
    /** [服务端返回]蛇卸载 */
    S2C_SNAKE_UNLOAD = 401,
    /** [服务端返回]蛇节点卸载 */
    S2C_SNAKE_NODE_UNLOAD = 402,
    /** [服务端返回]食物更新 */
    S2C_FOOD_UPDATE = 500,
    /** [服务端返回]食物卸载 */
    S2C_FOOD_UNLOAD = 501,
}

const ST = {
    SIZE_UINT: () => [["w", 5], ["h", 5]],
    SNAKE_NODE: () => [["id", 5], ["x", 12, 2], ["y", 12, 2], ["ang", 11, 2], ["idx", 5]],
    SNAKE: () => [["id", 5], ["name", 14], ["w", 11, 2], ["rgbs", 24, 1], ["nodes", 35, 1, ST.SNAKE_NODE()]],
    S2C_FOOD_UPDATE_FOOD: () => [["id", 5], ["x", 12, 2], ["y", 12, 2], ["w", 11, 2], ["rgb", 5]],
    S2C_FOOD_UNLOAD_FOODID: () => [["id", 5], ["eaterId", 5]],
}

const STRUCT: any = {
    100: [["name", 14]],
    101: [["id", 5], ["name", 14], ["worldSize", 16, ST.SIZE_UINT()]],
    102: [],
    200: [["score", 5], ["rank", 5]],
    201: [["ang", 11, 2]],
    202: [["isSprint", 0]],
    300: [["nodeId", 5]],
    400: [["snakes", 35, 1, ST.SNAKE()]],
    401: [["snakeIds", 24, 1]],
    402: [["nodeIds", 24, 1]],
    500: [["foods", 35, 1, ST.S2C_FOOD_UPDATE_FOOD()]],
    501: [["foodIds", 35, 1, ST.S2C_FOOD_UNLOAD_FOODID()]],
}

/** 协议Vo定义 */
export namespace ProtoVo {

    export type Def = {
        [Proto.C2S_JOIN]: IC2S_JOIN
        [Proto.S2C_JOIN]: IS2C_JOIN
        [Proto.C2S_READY]: IC2S_READY
        [Proto.S2C_PLAYER_INFO]: IS2C_PLAYER_INFO
        [Proto.C2S_CTRL_TURN]: IC2S_CTRL_TURN
        [Proto.C2S_CTRL_SPRINT]: IC2S_CTRL_SPRINT
        [Proto.S2C_SCREEN_FOCUS]: IS2C_SCREEN_FOCUS
        [Proto.S2C_SNAKE_UPDATE]: IS2C_SNAKE_UPDATE
        [Proto.S2C_SNAKE_UNLOAD]: IS2C_SNAKE_UNLOAD
        [Proto.S2C_SNAKE_NODE_UNLOAD]: IS2C_SNAKE_NODE_UNLOAD
        [Proto.S2C_FOOD_UPDATE]: IS2C_FOOD_UPDATE
        [Proto.S2C_FOOD_UNLOAD]: IS2C_FOOD_UNLOAD
    }

    /** 二进制数据转换为协议vo */
    export function fromBytes(bytes: Uint8Array) {
        let protocol: number, data = ObjDecoder.decodeDeal(bytes, (r: any) => { protocol = r.uint; return STRUCT[protocol] })
        return { protocol, data }
    }

    /** 协议vo转换为二进制数据 */
    export function toBytes<P extends keyof Def>(protocol: P, data: Def[P]) {
        return ObjEncoder.encodeDeal(data, STRUCT[protocol], (w: any) => w.uint = protocol)
    }

    /** 宽高(正整型) */
    export interface ISIZE_UINT {
        /** 宽 */
        w: number
        /** 高 */
        h: number
    }

    /** 蛇节点 */
    export interface ISNAKE_NODE {
        /** 节点id */
        id: number
        /** 坐标x */
        x: number
        /** 坐标y */
        y: number
        /** 角度 */
        ang: number
        /** 第几节点 */
        idx: number
    }

    /** 蛇 */
    export interface ISNAKE {
        /** 蛇id */
        id: number
        /** 蛇名 */
        name: string
        /** 宽度 */
        w: number
        /** 颜色整型 */
        rgbs: number[]
        /** 蛇节点数组 */
        nodes: ISNAKE_NODE[]
    }

    /** [客户端请求]加入游戏 */
    export interface IC2S_JOIN {
        /** 蛇名称 */
        name: string
    }

    /** [服务端返回]加入游戏结果 */
    export interface IS2C_JOIN {
        /** 玩家id */
        id: number
        /** 玩家名称 */
        name: string
        /** 世界宽高 */
        worldSize: ISIZE_UINT
    }

    /** [客户端请求]准备好接收数据了 */
    export interface IC2S_READY {
    }

    /** [服务端返回]玩家信息 */
    export interface IS2C_PLAYER_INFO {
        /** 得分 */
        score: number
        /** 排名 */
        rank: number
    }

    /** [客户端请求]控制角度 */
    export interface IC2S_CTRL_TURN {
        /** 角度 */
        ang: number
    }

    /** [客户端请求]控制加速 */
    export interface IC2S_CTRL_SPRINT {
        /** 是否加速 */
        isSprint: boolean
    }

    /** [服务端返回]屏幕焦点 */
    export interface IS2C_SCREEN_FOCUS {
        /** 蛇节点id */
        nodeId: number
    }

    /** [服务端返回]蛇更新 */
    export interface IS2C_SNAKE_UPDATE {
        /** 蛇数组 */
        snakes: ISNAKE[]
    }

    /** [服务端返回]蛇卸载 */
    export interface IS2C_SNAKE_UNLOAD {
        /** 蛇id数组 */
        snakeIds: number[]
    }

    /** [服务端返回]蛇节点卸载 */
    export interface IS2C_SNAKE_NODE_UNLOAD {
        /** 蛇节点id数组 */
        nodeIds: number[]
    }

    /** [服务端返回]食物更新 */
    export interface IS2C_FOOD_UPDATE {
        /** 食物数组 */
        foods: IS2C_FOOD_UPDATE_FOOD[]
    }

    /** 食物 */
    export interface IS2C_FOOD_UPDATE_FOOD {
        /** 食物id */
        id: number
        /** 坐标x */
        x: number
        /** 坐标y */
        y: number
        /** 宽度 */
        w: number
        /** 颜色整型(+1) 0是随机颜色 */
        rgb?: number
    }

    /** [服务端返回]食物卸载 */
    export interface IS2C_FOOD_UNLOAD {
        /** 食物id数组 */
        foodIds: IS2C_FOOD_UNLOAD_FOODID[]
    }

    /** 卸载食物 */
    export interface IS2C_FOOD_UNLOAD_FOODID {
        /** 食物id */
        id: number
        /** 吃了食物的蛇节点id */
        eaterId?: number
    }

}